package com.ygqh.baby.controller.mobile;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.mp.model.OauthToken;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.AppType;
import com.ygqh.baby.ao.Message;
import com.ygqh.baby.ao.UserType;
import com.ygqh.baby.ao.ValidateCode;
import com.ygqh.baby.constant.RedisConstant;
import com.ygqh.baby.exception.YgException;
import com.ygqh.baby.handler.HolidayNoticeHandler;
import com.ygqh.baby.model.YgLoginModel;
import com.ygqh.baby.model.YgUserModel;
import com.ygqh.baby.po.YgUser;
import com.ygqh.baby.po.YgUserBalance;
import com.ygqh.baby.po.YgUserOpen;
import com.ygqh.baby.service.*;
import com.ygqh.baby.service.impl.DocumentConstant;
import com.ygqh.baby.service.impl.PasswordHelper;
import com.ygqh.baby.service.task.YgAsynClient;
import com.ygqh.baby.utils.*;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Controller
@RequestMapping("/mobile/admin")
public class AdminController {

    private Logger logger = Logger.getLogger(AdminController.class);

    @Autowired
    private YgUserService ygUserService;
    @Autowired
    private YgUserOpenService ygUserOpenService;
    @Autowired
    private WxMpAuthorityService wxMpAuthorityService;
    @Autowired
    private YgCouponService ygCouponService;
    @Autowired
    private YgAsynClient ygAsynClient;
    @Autowired
    private YgCardCouponDetailService ygCardCouponDetailService;
    @Autowired
    private SmsService smsService;

    @Value("${validate.send.count}")
    private Long validateSendCount;

    @Value("${validate.send.interval}")
    private Long validateSendInterval;

    @Value("${validate.valid.time}")
    private Long validateValidTime;
    @Autowired
    private YgUserBalanceService userBalanceService;

    @Value("${default.head.url}")
    private String defaultHeadUrl;
    @Value("${default.nickName.prefix}")
    private String defaultNickNamePrefix;

    @Autowired
    private DocumentConstant documentConstant;

    @Value("${sms.isSend}")
    private Boolean isSend;

    @RequestMapping(value = "/unauthorized")
    @ResponseBody
    public JSONPObject unauthorized(String callback) {
        return new JSONPObject(callback, Message.success(new YgLoginModel("REDIRECT_LONGIN_PAGE", documentConstant.REDIRECT_LONGIN_PAGE)));
    }

    /**
     * 是否登录
     *
     * @param callback
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/isLogin")
    @ResponseBody
    public JSONPObject isLogin(@RequestParam(required = true) String callback, HttpServletRequest request) throws Exception {
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        Map<String, Object> data = new HashMap<>();
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            YgUser user = (YgUser) subject.getPrincipal();
            data.put("userId", user.getId());
            data.put("sessionId", subject.getSession().getId());
            model.setIsBand(!StringUtils.isBlank(user.getTelPhone()));
        }
        model.setUser(data);

        return new JSONPObject(callback, Message.success(model));
    }

    /**
     * 判断是否是新客
     *
     * @param callback
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/isNewCustom")
    @ResponseBody
    public JSONPObject isNewCustom(@RequestParam(required = true) String callback, HttpServletRequest request) throws Exception {
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        YgUser user = SessionUtil.getCurrentUser();
        model.setUser(ygUserService.isNewCustom(user.getId()));
        return new JSONPObject(callback, Message.success(model));
    }

    /**
     * 登录
     *
     * @param username
     * @param password
     * @param callback
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login")
    @ResponseBody
    public JSONPObject login(@RequestParam(required = true) String username, @RequestParam(required = true) String password,
                             @RequestParam(required = true) String callback, HttpServletRequest request, HttpServletResponse response) throws Exception {

        // YgUser user = userService.findByUserName(username);
        //
        // PrincipalCollection principals = new SimplePrincipalCollection( user,
        // "MobileRealm");
        // Builder builder = new WebSubject.Builder(request, response);
        // builder.principals(principals);
        // builder.authenticated(true);
        // WebSubject subject = builder.buildWebSubject();
        // ThreadContext.bind(subject);
        // YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS",
        // DocumentConstant.LOGIN_SUCCESS);
        // model.setUser(subject.getPrincipal());
        // return new JSONPObject(callback, Message.success(model));

        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
        } catch (IncorrectCredentialsException e) {
            model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
        } catch (Exception e) {
            e.printStackTrace();
            model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
        }
        ;
        logger.debug("session id===============" + request.getSession().getId());
        if (model.getKey().equals("LOGIN_SUCCESS")) {
            model.setUser(subject.getPrincipal());
            return new JSONPObject(callback, Message.success(model));
        } else {
            return new JSONPObject(callback, Message.error(model));
        }
    }

    /**
     * 登录
     *
     * @param request
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login4OpenId")
    @ResponseBody
    public JSONPObject login4OpenId(@RequestParam(required = true) String openId, @RequestParam(required = true) String callback, HttpServletRequest request,
                                    HttpServletResponse response) throws Exception {

        YgUser user = ygUserService.findByOpenId(openId);
        if (null != user) {
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(user.getUserName(), user.getPassword());

            YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
            try {
                subject.login(token);
            } catch (UnknownAccountException e) {
                model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
            } catch (IncorrectCredentialsException e) {
                model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
            } catch (Exception e) {
                e.printStackTrace();
                model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
            }
            ;
            logger.debug("session id===============" + request.getSession().getId());
            if (model.getKey().equals("LOGIN_SUCCESS")) {
                model.setUser(subject.getPrincipal());
                return new JSONPObject(callback, Message.success(model));
            } else {
                return new JSONPObject(callback, Message.error(model));
            }
        } else {
            return new JSONPObject(callback, Message.error(null));
        }
    }

    @RequestMapping(value = "/findOpendId")
    @ResponseBody
    public JSONPObject findOpendId(@RequestParam(required = true) String code, @RequestParam(required = true) String callback) throws WeixinException {
        OauthToken token = wxMpAuthorityService.findOauthToken(code);
        if (token == null) {
            return new JSONPObject(callback, Message.success(null));
        }
        String openId = token.getOpenId();
        return new JSONPObject(callback, Message.success(openId));
    }

    @RequestMapping("/testGetValidateCode")
    @ResponseBody
    public JSONPObject testGetValidateCode(@RequestParam(required = true) String username, @RequestParam(required = true) String callback) {
        ValidateCode originalValidateCode = ygUserService.selectValidateCodeToRedis(username);
        return new JSONPObject(callback, Message.success(documentConstant.VALIDATE_CODE_SEND_SUCCESS, originalValidateCode.getCode()));
    }

    /**
     * 发送验证码-----------------------正常
     *
     * @param username
     * @param callback
     * @return
     * @throws Exception
     */
    @RequestMapping("/sendValidateCode")
    @ResponseBody
    public JSONPObject sendValidateCode(@RequestParam(required = true) String username, @RequestParam(required = true) String callback) throws Exception {
        String validateCodeString;
        if (isSend) {
            validateCodeString = CommonUtil.generatorSmsValidateCode() + "";
        } else {
            validateCodeString = "123456";
        }
        ValidateCode originalValidateCode = ygUserService.selectValidateCodeToRedis(username);
        ValidateCode validateCode = new ValidateCode(validateCodeString, 0L);
        logger.debug("sendValidateCode===========" + validateCode);
        if (originalValidateCode != null) {
            // 判断发送信息次数是否超过限定值
            if (originalValidateCode.getSendCount() > validateSendCount) {
                return new JSONPObject(callback, Message.error(documentConstant.SEND_COUNT_OVER, "SEND_COUNT_OVER"));
            }

            if (originalValidateCode.getSendCount() > 1) {
                // 判断是否发送过于频繁
                Long currentTime = System.currentTimeMillis();
                System.out.println((currentTime - originalValidateCode.getSendTime()) / 1000 + "----------------------------------");
                if ((currentTime - originalValidateCode.getSendTime()) / 1000 < validateSendInterval) {
                    return new JSONPObject(callback, Message.error(documentConstant.SEND_HIGH_FREQUENCY, "SEND_HIGH_FREQUENCY"));
                }
            }

            Long count = originalValidateCode.getSendCount() + 1L;
            validateCode.setSendCount(count);
            validateCode.setSendTime(System.currentTimeMillis());
        } else {
            validateCode.setSendTime(System.currentTimeMillis());
        }
        String smsContent = PropertiesUtil.get("/prop/sms.properties", "sms.content", new String[]{validateCodeString});
        smsService.sendSms(username, smsContent, true);
        int expire = (validateValidTime.intValue() * 60 * 1000);
        ygUserService.saveValidateCodeToRedis(username, validateCode, expire);
        return new JSONPObject(callback, Message.success(documentConstant.VALIDATE_CODE_SEND_SUCCESS, documentConstant.VALIDATE_CODE_SEND_SUCCESS));
    }

    /**
     * 注册
     *
     * @param username
     * @param password
     * @param validateCode
     * @param callback
     * @return
     */
    @RequestMapping("/register")
    @ResponseBody
    public JSONPObject register(@RequestParam String username, @RequestParam String password,
                                @RequestParam String validateCode, @RequestParam String callback, String fromCode, String groupTag) {
        ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(username);
        YgUser ygUser;
        // 判断是否匹配
        if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING"));
        }

        Long currentTime = System.currentTimeMillis();
        Long minute = (currentTime - rightValidateCode.getSendTime()) / 1000 / 60;
        logger.debug("reigster===" + minute);

        // 判断是否失效
        if (minute > validateValidTime) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_INVALID, "VALIDATE_INVALID"));
        }

        if (ygUserService.findByUserName(username) != null) {
            return new JSONPObject(callback, Message.error(documentConstant.USER_SAVED, "USER_SAVED"));
        } else {
            ygUser = new YgUser();
            ygUser.setUserName(username);
            ygUser.setPassword(password);
            ygUser.setTelPhone(username);
            ygUser.setFromCode(fromCode);
            ygUser.setSourceCode(username);
            ygUser.setBabyBirthday(null);
            ygUser.setBabyGender(null);
            ygUser.setGender(null);
            ygUser.setHeadImageUrl(defaultHeadUrl);
            ygUser.setGroupTag(groupTag);
            ygUser.setAppType(AppType.WeChat);
            if (username.length() >= 7) {
                ygUser.setNickName(defaultNickNamePrefix + username.substring(7, 11));
            }
            ygUser.setCreateTime(new Date());

            ygUserService.save(ygUser);

            YgUserBalance userBalance = new YgUserBalance();
            userBalance.setBalancePrice(new BigDecimal(0));
            userBalance.setCreateTime(new Date());
            userBalance.setFreezePrice(new BigDecimal(0));
            userBalance.setPreincomePrice(new BigDecimal(0));
            userBalance.setUserId(ygUser.getId());
            userBalance.setWithdrawPrice(new BigDecimal(0));
            userBalanceService.save(userBalance);

            doPullNEWBussness(fromCode, ygUser.getUserName(), ygUser.getNickName(), null);

            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
            ygUser.setIsNewCustomer(true);

            // 注册新用户赠送拉新卡券
            ygCardCouponDetailService.asyncGivePullNewCard(ygUser.getId());
        }
        return new JSONPObject(callback, Message.success(documentConstant.REIGSTER_SUCCESS, ygUser));

    }

    @RequestMapping("/updateFromCode")
    @ResponseBody
    public JSONPObject updateFromCode(@RequestParam(required = true) String username, @RequestParam(required = true) String fromCode,
                                      @RequestParam(required = true) String callback) {
        YgUser user = ygUserService.findByUserName(username);
        if (user == null) {
            return new JSONPObject(callback, Message.error(documentConstant.USER_NULL, "USER_NULL"));
        }
        user.setFromCode(fromCode);
        ygUserService.update(user);
        return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS, "MESSAGE_SUCCESS"));
    }

    @RequestMapping("/index")
    public String index(Model model) {
        YgUser user = SessionUtil.getCurrentUser();
        model.addAttribute("user", user);
        return "index";
    }

    /**
     * 用户是否存在
     *
     * @param username
     * @param callback
     * @return
     */
    @RequestMapping("/userIsExist")
    @ResponseBody
    public JSONPObject userIsExist(@RequestParam(required = true) String username, @RequestParam(required = true) String callback) {
        YgUser user = ygUserService.findByUserName(username);
        if (user == null) {
            return new JSONPObject(callback, Message.success(false));
        } else {
            return new JSONPObject(callback, Message.success(true));
        }
    }

    /**
     * 忘记密码
     *
     * @param username
     * @param password
     * @param validateCode
     * @param callback
     * @return
     */
    @RequestMapping("/forgetPassword")
    @ResponseBody
    public JSONPObject forgetPassword(@RequestParam(required = true) String username, @RequestParam(required = true) String password,
                                      @RequestParam(required = true) String validateCode, @RequestParam(required = true) String callback) {
        ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(username);

        // 判断是否匹配
        if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING"));
        }

        Long currentTime = System.currentTimeMillis();
        Long minute = (currentTime - rightValidateCode.getSendTime()) / 1000 / 60;
        logger.debug("reigster===" + minute);

        // 判断是否失效
        if (minute > validateValidTime) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_INVALID, "VALIDATE_INVALID"));
        }
        YgUser user = ygUserService.findByUserName(username);
        if (user == null) {
            return new JSONPObject(callback, Message.error(documentConstant.USER_NULL, "USER_NULL"));
        } else {
            user.setPassword(password);
            ygUserService.update(user);
        }
        return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS));

    }

    @RequestMapping(value = "logout", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject logout(HttpServletRequest request, @RequestParam(required = true) String callback) throws Exception {
        try {
            Subject subject = SecurityUtils.getSubject();
            subject.logout();

        } catch (Exception e) {
            e.printStackTrace();
        }
        return new JSONPObject(callback, Message.success(documentConstant.MESSAGE_SUCCESS));
    }

    /**
     * 绑定手机号
     */
    @RequestMapping(value = "bind", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject bind(@RequestParam(required = true) String callback, @RequestParam(required = true) String username, String password,
                            @RequestParam(required = true) String validateCode, @RequestParam(required = true) String openId, Boolean isSamll, HttpServletRequest request)
            throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        YgUserOpen ygUserOpen = null;
        try {
            if (isSamll != null && isSamll) {
                ygUserOpen = ygUserOpenService.findBySmallOpenId(openId);
            } else {
                ygUserOpen = ygUserOpenService.findByOpenId(openId);
            }
            ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(username);

            // 判断是否匹配
            if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
                return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING"));
            }
            YgUser user = ygUserService.findByUserName(username);
            // 改手机号已经注册过
            if (user != null) {
                if (user.getOpenId() != null) {
                    return new JSONPObject(callback, Message.error("该手机号已绑定过，请输入其他手机号", username));
                }
                if (isSamll != null && isSamll) {
                    // 设置小程序的openId
                    user.setSmallOpenId(ygUserOpen.getSmallOpenId());
                } else {
                    user.setOpenId(ygUserOpen.getOpenId());
                }
                user.setUuid(ygUserOpen.getUuid());
                user.setNickName(ygUserOpen.getNickName());
                user.setHeadImageUrl(ygUserOpen.getHeadImageUrl());
                if (user.getFromCode() == null) {
                    if (ygUserOpen.getFromCode() != null) {
                        user.setFromCode(ygUserOpen.getFromCode());
                    }
                }
                ygUserService.updateWxData(user.getId(), user.getOpenId(), user.getSmallOpenId(), user.getUuid(), user.getNickName(), user.getHeadImageUrl(),
                        user.getFromCode());
                user.setIsNewCustomer(ygUserService.isNewCustom(user.getId()));

            } else {
                user = new YgUser();
                BeanUtils.copyProperties(ygUserOpen, user);
                user.setUserName(username);
                user.setPassword("123456a");
                user.setTelPhone(username);
                user.setSourceCode(username);
                user.setCreateTime(new Date());
                user.setId(null);
                if (isSamll) {
                    user.setAppType(AppType.Small);
                } else {
                    user.setAppType(AppType.WeChat);
                }
                ygUserService.save(user);

                YgUserBalance userBalance = new YgUserBalance();
                userBalance.setBalancePrice(new BigDecimal("0.00"));
                userBalance.setCreateTime(new Date());
                userBalance.setFreezePrice(new BigDecimal("0.00"));
                userBalance.setPreincomePrice(new BigDecimal("0.00"));
                userBalance.setUserId(user.getId());
                userBalance.setWithdrawPrice(new BigDecimal("0.00"));
                userBalanceService.save(userBalance);
                user.setIsNewCustomer(true);

                doPullNEWBussness(user.getFromCode(), user.getUserName(), user.getNickName(), user.getOpenId());

                // 注册新用户赠送拉新卡券
                ygCardCouponDetailService.asyncGivePullNewCard(user.getId());
            }

            if (user.getFromCode().endsWith("wxddjtxd0316")) {
                ygCouponService.receiveCoupon(257L, user);
            }

            // 登录
            this.loginSilent(username, user.getPassword());
            map.put("user", user);
            String sessionId = request.getSession().getId();
            map.put("sessionId", sessionId);
        } catch (Exception e) {
            logger.error(e.getMessage() + ";绑定手机号失败：username=" + username + ";openId=" + openId + ";isSamll=" + isSamll);
            e.printStackTrace();
        }
        return new JSONPObject(callback, Message.success(map));
    }

    /**
     * 处理拉新
     *
     * @param fromCode
     * @param userName
     * @param nickName
     */
    private void doPullNEWBussness(String fromCode, String userName, String nickName, String openId) {
        try {
            YgUser fromUser = ygUserService.findBySourceCode(fromCode);
            if (fromUser != null && fromUser.getUserType().equals(UserType.UserAgent)) {
                // 发送微信消息
                ygAsynClient.sendInviteRegisterSuccessMsg(fromUser.getOpenId(), fromCode, userName, nickName);
            }
            /*
             * ygDrawPrizeHelpService.addWxHelp(fromCode, openId,
             * DataStatus.Valid);
             */
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "wxAuthorization", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject wxAuthorization(@RequestParam(required = true) String callback, @RequestParam(required = true) String code, String fromCode,
                                       String groupTag) {
        Map<String, Object> map = new HashMap<String, Object>();
        YgUser ygUser = SessionUtil.getCurrentUser();
        // 已经登录，且openId 已存在
        if (ygUser != null && StringUtil.isNotBlank(ygUser.getOpenId())) {
            ygUser.setIsNewCustomer(ygUserService.isNewCustom(ygUser.getId()));
            map.put("user", ygUser);
            map.put("isBand", true);
            map.put("openId", ygUser.getOpenId());
            if (fromCode.endsWith("wxddjtxd0316")) {
                ygCouponService.receiveCoupon(257L, ygUser);
            }
            return new JSONPObject(callback, Message.success(map));
        }
        Boolean isBind = true;
        User wxUser = null;
        try {
            wxUser = wxMpAuthorityService.findUserInfo(code);
        } catch (WeixinException e) {
            e.printStackTrace();
            String message = e.getMessage();
            logger.error("wxAuthorization:code=" + code + ";" + e.getMessage() + ";" + fromCode);
            return new JSONPObject(callback, Message.error(message));
        }
        System.out.println("wxUser:【" + wxUser.toString() + "】");
        String openId = wxUser.getOpenId();
        YgUser user = ygUserService.findByUuid(wxUser.getUnionId());
        // 用户不存在，新增一个用户
        if (user == null) {
            Boolean exit = ygUserOpenService.existWxAuthorization(openId, fromCode);
            if (!exit) {
                YgUserOpen userOpen = new YgUserOpen();
                userOpen.setUserName(openId);
                userOpen.setPassword("123456a");
                userOpen.setTelPhone("");
                userOpen.setFromCode(fromCode);
                userOpen.setSourceCode("");
                userOpen.setBabyBirthday(null);
                userOpen.setBabyGender(null);
                userOpen.setGender(null);
                userOpen.setOpenId(openId);
                userOpen.setUuid(wxUser.getUnionId());
                userOpen.setGroupTag(groupTag);
                if (StringUtil.isNotBlank(wxUser.getHeadimgurl())) {
                    userOpen.setHeadImageUrl(wxUser.getHeadimgurl());
                } else {
                    userOpen.setHeadImageUrl(defaultHeadUrl);
                }
                userOpen.setNickName(wxUser.getNickName());
                userOpen.setCreateTime(new Date());
                ygUserOpenService.save(userOpen);

            }
            isBind = false;
        } else {
            // 存在的话 更新微信openId
            ygUserService.bindingOpenId(user.getId(), openId, null, wxUser.getUnionId());
            this.loginSilent(user.getUserName(), user.getPassword());
            user.setIsNewCustomer(ygUserService.isNewCustom(user.getId()));
            map.put("user", user);
        }

        map.put("isBand", isBind);
        map.put("openId", openId);
        return new JSONPObject(callback, Message.success(map));
    }

    @RequestMapping(value = "isGuide", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject isGuide(@RequestParam(required = true) String callback) throws Exception {
        Boolean flag = ygUserService.isGuide(SessionUtil.getCurrentUser().getId());
        return new JSONPObject(callback, Message.success(flag));
    }

    @RequestMapping(value = "findUserById", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject findUserById(@RequestParam(required = true) String callback, @RequestParam(required = true) Long userId) throws Exception {
        YgUserModel userInfo = ygUserService.findUserInfo(userId);
        if (userInfo == null) {
            return new JSONPObject(callback, Message.success(null));
        }
        String birthday = DateConvertUtils.getBabyBirthday(userInfo.getBabyBirthday());
        userInfo.setbBirthday(birthday);
        JSONPObject json = new JSONPObject(callback, Message.success(userInfo));
        return json;
    }

    private YgLoginModel loginSilent(String username, String pwd) {
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, pwd);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        try {
            subject.login(token);
            model.setSessionId(subject.getSession().getId());
        } catch (UnknownAccountException e) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
        } catch (IncorrectCredentialsException e) {
            model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
        } catch (Exception e) {
            e.printStackTrace();
            model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
        }
        if (model.getKey().equals("LOGIN_SUCCESS")) {
            model.setUser(subject.getPrincipal());
            return model;
        } else {
            return model;
        }
    }

    private YgLoginModel resetLoginSilent(String username, String pwd) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        UsernamePasswordToken token = new UsernamePasswordToken(username, pwd);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
        } catch (IncorrectCredentialsException e) {
            model = new YgLoginModel("INCORRECTCREDENTIALS", documentConstant.INCORRECTCREDENTIALS);
        } catch (Exception e) {
            e.printStackTrace();
            model = new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR);
        }
        if (model.getKey().equals("LOGIN_SUCCESS")) {
            model.setUser(subject.getPrincipal());
            model.setSessionId(subject.getSession().getId());
            return model;
        } else {
            return model;
        }
    }

    /**
     * 验证码登录
     *
     * @param username
     * @param callback
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/validateCodeLogin")
    @ResponseBody
    public JSONPObject validateCodeLogin(@RequestParam(required = true) String username, @RequestParam(required = true) String validateCode,
                                         @RequestParam(required = true) String callback, HttpServletRequest request, HttpServletResponse response) throws Exception {

        YgUser user = ygUserService.findByUserName(username);
        YgLoginModel model = new YgLoginModel("LOGIN_SUCCESS", documentConstant.LOGIN_SUCCESS);

        if (user == null) {
            model = new YgLoginModel("UNKNOWN_ACCOUNT", documentConstant.UNKNOWN_ACCOUNT);
            return new JSONPObject(callback, Message.error(model));
        }

        ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(username);

        // 判断是否匹配
        if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING"));
        }

        Long currentTime = System.currentTimeMillis();
        Long minute = (currentTime - rightValidateCode.getSendTime()) / 1000 / 60;

        // 判断是否失效
        if (minute > validateValidTime) {
            return new JSONPObject(callback, Message.error(documentConstant.VALIDATE_INVALID, "VALIDATE_INVALID"));
        }

        this.loginSilent(username, user.getPassword());
        user.setIsNewCustomer(ygUserService.isNewCustom(user.getId()));
        model.setUser(user);
        return new JSONPObject(callback, Message.success(model));

    }

    @RequestMapping(value = "autoLogin", method = RequestMethod.GET)
    @ResponseBody
    public JSONPObject autoLogin(@RequestParam(required = true) String callback, @RequestParam(required = true) String userName) throws Exception {
        YgUser user = SessionUtil.getCurrentUser();
        if (user == null) {
            user = ygUserService.findBySourceCode(userName);
            if (user != null && user.getOpenId() != null) {
                this.loginSilent(user.getUserName(), user.getPassword());
            } else {
                return new JSONPObject(callback, Message.error(new YgLoginModel("UNKNOWN_ERROR", documentConstant.UNKNOWN_ERROR)));
            }
        }
        user.setIsNewCustomer(ygUserService.isNewCustom(user.getId()));

        return new JSONPObject(callback, Message.success(user));

    }

    @RequestMapping(value = "getImgCode", method = RequestMethod.GET)
    public void getImgCode(HttpServletRequest request, HttpServletResponse response) throws YgException, IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");
        // 生成随机字串
        String attribute = (String) request.getSession().getAttribute(RedisConstant.MOBILE_IMG_VALIDATE_CODE);
        System.out.println(attribute);
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        request.getSession().setAttribute(RedisConstant.MOBILE_IMG_VALIDATE_CODE, verifyCode.toLowerCase());
        // 生成图片
        VerifyCodeUtils.outputImage(100, 50, response.getOutputStream(), verifyCode);
    }

    @RequestMapping("/sendValidateCodeNew")
    @ResponseBody
    public JSONPObject sendValidateCodeNew(@RequestParam(required = true) String username, String imgCode, @RequestParam(required = true) String callback,
                                           HttpServletRequest request) throws Exception {
        String validateCodeString;
        if (isSend) {
            validateCodeString = CommonUtil.generatorSmsValidateCode() + "";
        } else {
            validateCodeString = "123456";
        }
        ValidateCode originalValidateCode = ygUserService.selectValidateCodeToRedis(username);
        ValidateCode validateCode = new ValidateCode(validateCodeString, 1L);
        logger.debug("sendValidateCode===========" + validateCode);
        if (originalValidateCode != null) {
            // 判断发送信息次数是否超过限定值,需要输入图片验证码
            if (originalValidateCode.getSendCount() > validateSendCount) {
                String imgVerifyCode = (String) request.getSession().getAttribute(RedisConstant.MOBILE_IMG_VALIDATE_CODE);
                if (!imgVerifyCode.equals(imgCode)) {
                    return new JSONPObject(callback, Message.error("图片验证码输入错误.", null));
                }
            }

            Long count = originalValidateCode.getSendCount() + 1L;
            validateCode.setSendCount(count);
        }
        String smsContent = PropertiesUtil.get("/prop/sms.properties", "sms.content", new String[]{validateCodeString});
        smsService.sendSms(username, smsContent, true);
        int expire = (validateValidTime.intValue() * 60 * 1000);
        ygUserService.saveValidateCodeToRedis(username, validateCode, expire);
        return new JSONPObject(callback, Message.success(documentConstant.VALIDATE_CODE_SEND_SUCCESS, validateCode.getSendCount()));
    }

    @RequestMapping("/relatePhoneNo")
    @ResponseBody
    public JSONPObject relatePhoneNo(@RequestParam(required = true) String phoneNo, @RequestParam(required = true) String validateCode, String callback)
            throws Exception {
        Message message = this.checkValidCode(validateCode, phoneNo);
        if (message.getType().equals(Message.Type.error)) {
            return new JSONPObject(callback, message);
        }
        YgUser currentUser = SessionUtil.getCurrentUser();
        YgUser user = ygUserService.findByUserName(phoneNo);
        if (user == null) {
            user = new YgUser();
            user.setId(currentUser.getId());
            user.setUserName(phoneNo);
            user.setSourceCode(phoneNo);
            user.setTelPhone(phoneNo);
            user.setUpdateTime(new Date());
            user.setPassword("123456a");
            new PasswordHelper().encryptPassword(user);
            ygUserService.updateUserInfo(user);
        } else {
            if (StringUtils.isNotBlank(user.getSmallOpenId())) {
                return new JSONPObject(callback, Message.error("该用户已关联小程序", null));
            }
            user.setSmallOpenId(currentUser.getSmallOpenId());
            user.setUuid(currentUser.getUuid());
            user.setUpdateTime(new Date());
            ygUserService.update(user);
            Message msg = ygUserService.transferData(currentUser, user);
            if (msg.getType().equals(Message.Type.error)) {
                return new JSONPObject(callback, msg);
            }

        }

        YgLoginModel model = this.resetLoginSilent(user.getUserName(), user.getPassword());
        return new JSONPObject(callback, Message.success(model));
    }

    private Message checkValidCode(String validateCode, String phoneNo) {
        ValidateCode rightValidateCode = ygUserService.selectValidateCodeToRedis(phoneNo);

        // 判断是否匹配
        if (rightValidateCode == null || !rightValidateCode.getCode().equals(validateCode)) {
            return Message.error(documentConstant.VALIDATE_CODE_NO_MATCHING, "VALIDATE_CODE_NO_MATCHING");
        }

        Long currentTime = System.currentTimeMillis();
        Long minute = (currentTime - rightValidateCode.getSendTime()) / 1000 / 60;

        // 判断是否失效
        if (minute > validateValidTime) {
            Message.error(documentConstant.VALIDATE_INVALID, "VALIDATE_INVALID");
        }
        return Message.success(null);
    }

    @RequestMapping(value = "loginByUnionId")
    @ResponseBody
    public JSONPObject loginByUnionId(@RequestParam(required = true) String unionId, String callback) throws Exception {
        YgUser user = ygUserService.findByUuid(unionId);
        if (user != null) {
            YgLoginModel loginSilent = this.loginSilent(user.getUserName(), user.getPassword());
            return new JSONPObject(callback, Message.success(loginSilent));
        } else {
            return new JSONPObject(callback, Message.error("用户不存在", unionId));
        }
    }

    @Autowired
    private HolidayNoticeHandler holidayNoticeHandler;

    @RequestMapping("getHolidayNotice")
    @ResponseBody
    public JSONPObject getHolidayNotice(String callback, @RequestParam(defaultValue = "true") Boolean checkDate) {
        Map holidayNotice = holidayNoticeHandler.getHolidayNotice(checkDate);
        return new JSONPObject(callback, Message.success(holidayNotice));
    }
}
